Interleaving string¶
Time: O(MxN); Space: O(M+N); hard
Given three strings: s1, s2, s3, determine whether s3 is formed by the interleaving of s1 and s2.
Example 1:
Input: s1 = “aabcc”, s2 = “dbbca”, s3 = “aadbbcbcac”
Output: True
Example 2:
Input: s1 = “aabcc”, s2 = “dbbca”, s3 = “aadbbbaccc”
Output: False
1.¶
[1]:
class Solution1(object):
"""
Time: O(M*N)
Space: O(M+N)
"""
def isInterleave(self, s1, s2, s3):
"""
:type s1: str
:type s2: str
:type s3: str
:rtype: a boolean
"""
if len(s1) + len(s2) != len(s3):
return False
if len(s1) > len(s2):
return self.isInterleave(s2, s1, s3)
match = [False for i in range(len(s1) + 1)]
match[0] = True
for i in range(1, len(s1) + 1):
match[i] = match[i -1] and s1[i - 1] == s3[i - 1]
for j in range(1, len(s2) + 1):
match[0] = match[0] and s2[j - 1] == s3[j - 1]
for i in range(1, len(s1) + 1):
match[i] = (match[i - 1] and s1[i - 1] == s3[i + j - 1]) \
or (match[i] and s2[j - 1] == s3[i + j - 1])
return match[-1]
[2]:
s = Solution1()
s1 = "aabcc"
s2 = "dbbca"
s3 = "aadbbcbcac"
assert s.isInterleave(s1, s2, s3) == True
s1 = "aabcc"
s2 = "dbbca"
s3 = "aadbbbaccc"
assert s.isInterleave(s1, s2, s3) == False
2. Dynamic Programming¶
[3]:
class Solution2(object):
def isInterleave(self, s1, s2, s3):
"""
:type s1: str
:type s2: str
:type s3: str
:rtype: a boolean
"""
if len(s1) + len(s2) != len(s3):
return False
match = [[False for i in range(len(s2) + 1)] for j in range(len(s1) + 1)]
match[0][0] = True
for i in range(1, len(s1) + 1):
match[i][0] = match[i - 1][0] and s1[i - 1] == s3[i - 1]
for j in range(1, len(s2) + 1):
match[0][j] = match[0][j - 1] and s2[j - 1] == s3[j - 1]
for i in range(1, len(s1) + 1):
for j in range(1, len(s2) + 1):
match[i][j] = (match[i - 1][j] and s1[i - 1] == s3[i + j - 1]) \
or (match[i][j - 1] and s2[j - 1] == s3[i + j - 1])
return match[-1][-1]
[4]:
s = Solution2()
s1 = "aabcc"
s2 = "dbbca"
s3 = "aadbbcbcac"
assert s.isInterleave(s1, s2, s3) == True
s1 = "aabcc"
s2 = "dbbca"
s3 = "aadbbbaccc"
assert s.isInterleave(s1, s2, s3) == False
3. Recursive + Hash¶
[5]:
class Solution3(object):
def isInterleave(self, s1, s2, s3):
"""
:type s1: str
:type s2: str
:type s3: str
:rtype: a boolean
"""
self.match = {}
if len(s1) + len(s2) != len(s3):
return False
return self.isInterleaveRecu(s1, s2, s3, 0, 0, 0)
def isInterleaveRecu(self, s1, s2, s3, a, b, c):
if repr([a, b]) in self.match.keys():
return self.match[repr([a, b])]
if c == len(s3):
return True
result = False
if a < len(s1) and s1[a] == s3[c]:
result = result or self.isInterleaveRecu(s1, s2, s3, a + 1, b, c + 1)
if b < len(s2) and s2[b] == s3[c]:
result = result or self.isInterleaveRecu(s1, s2, s3, a, b + 1, c + 1)
self.match[repr([a, b])] = result
return result
[6]:
s = Solution3()
s1 = "aabcc"
s2 = "dbbca"
s3 = "aadbbcbcac"
assert s.isInterleave(s1, s2, s3) == True
s1 = "aabcc"
s2 = "dbbca"
s3 = "aadbbbaccc"
assert s.isInterleave(s1, s2, s3) == False
See also:¶
https://leetcode.com/problems/interleaving-string
https://www.lintcode.com/problem/interleaving-string/description